﻿using Noke.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Noke.SOA.Client
{
    public class SOAClient : IDisposable
    {
        private string ip = "";
        private int port = 0;

        private TcpClient remoteServer = null;

        private SOAClient() { }

        public SOAClient(string _ip, int _port)
        {
            ip = _ip;
            port = _port;
            remoteServer = new TcpClient();                   //创建TCPClient类来与服务器通信；  
        }

        public byte[] Invoke(string uri, Dictionary<string, object> vari)
        {
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ip), port);     //远程服务器端地址；  
            remoteServer.Connect(remoteEP);                                  //调用connect方法连接远端服务器；
            // 发送信息
            Dictionary<string, Dictionary<string, object>> dic = new Dictionary<string, Dictionary<string, object>>();
            dic.Add(uri, vari);
            byte[] sendBuf = Util.Object2Bytes(dic);
            remoteServer.Client.Send(sendBuf);

            // 接收信息
            byte[] RecvBuf = new byte[1024 * 1024 * 10];                    //申请接收缓存；  
            int RecvBytes = 0;                                            //接收字节数；
            RecvBytes = remoteServer.Client.Receive(RecvBuf);                           //接受服务器发送过来的消息；              
            return RecvBuf;
        }

        #region Dispose

        //供程序员显式调用的Dispose方法
        public void Dispose()
        {
            //调用带参数的Dispose方法，释放托管和非托管资源
            Dispose(true);
            //手动调用了Dispose释放资源，那么析构函数就是不必要的了，这里阻止GC调用析构函数
            System.GC.SuppressFinalize(this);
        }

        //protected的Dispose方法，保证不会被外部调用。
        //传入bool值disposing以确定是否释放托管资源
        protected void Dispose(bool disposing)
        {
            if (disposing)
            {
                ///TODO:在这里加入清理"托管资源"的代码，应该是xxx.Dispose();
                if (remoteServer.Client != null)
                    remoteServer.Client.Dispose();
            }
            ///TODO:在这里加入清理"非托管资源"的代码
        }

        //供GC调用的析构函数
        ~SOAClient()
        {
            Dispose(false); // 释放非托管资源
        }

        #endregion
    }
}
